package com.runa.rccprotocol.dto.runa;

import com.runa.protocol.util.ByteUtil;
import com.runa.rccprotocol.constant.AppFunCode;
import com.runa.rccprotocol.dto.FrameStruct;
import org.apache.commons.lang3.ArrayUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class RunaICStruct implements FrameStruct {

    private int head = 0x68;

    private int length;

    private RunaFrameSequence.Control control;

    private RunaFrameSequence.Area area;

    private AppFunCode.rnicAFN afn;

    private RunaFrameSequence.Seq seq;

    private List<RunaFrameSequence.DataUnit> dataField = new ArrayList<>();

    private byte checksum;

    private int tail = 0x16;

    public int getLength() {
        return length;
    }

    public void setLength(int length) {
        this.length = length;
    }

    public List<RunaFrameSequence.DataUnit> getDataField() {
        return dataField;
    }

    public void addDataField(RunaFrameSequence.DataUnit dataUnit) {
        this.dataField.add(dataUnit);
    }

    public void addDataFields(Collection<RunaFrameSequence.DataUnit> dataUnits) {
        this.dataField.addAll(dataUnits);
    }

    public byte getChecksum() {
        return checksum;
    }

    public void setChecksum(byte checksum) {
        this.checksum = checksum;
    }

    public int getTail() {
        return tail;
    }

    public void setTail(int tail) {
        this.tail = tail;
    }

    public int getHead() {
        return head;
    }

    public void setHead(int head) {
        this.head = head;
    }

    public RunaFrameSequence.Control getControl() {
        return control;
    }

    public void setControl(RunaFrameSequence.Control control) {
        this.control = control;
    }

    public RunaFrameSequence.Area getArea() {
        return area;
    }

    public void setArea(RunaFrameSequence.Area area) {
        this.area = area;
    }

    public AppFunCode.rnicAFN getAfn() {
        return afn;
    }

    public void setAfn(AppFunCode.rnicAFN afn) {
        this.afn = afn;
    }

    public RunaFrameSequence.Seq getSeq() {
        return seq;
    }

    public void setSeq(RunaFrameSequence.Seq seq) {
        this.seq = seq;
    }

    @Override
    public byte[] getBuffer() {
        int dus = 0;
        for (RunaFrameSequence.DataUnit dataUnit : dataField) {
            dus += dataUnit.length();
        }
        length = 1 + 5 + 2 + dus; //C + A + afn + seq + data unit
        int L = (length << 2) | 2; //1111 1111 1111 1110B
        byte[] bytes = new byte[length + 8];
        //前段
        bytes[0] = (byte) this.head;
        bytes[1] = (byte) L;
        bytes[2] = (byte) (L >> 8);
        bytes[3] = (byte) L;
        bytes[4] = (byte) (L >> 8);
        bytes[5] = (byte) this.head;
        bytes[6] = control.getC();
        //中段
        System.arraycopy(area.getA(), 0, bytes, 7, 5);
        bytes[12] = (byte) afn.getCode();
        bytes[13] = seq.getSeq();
        dataBuffer(bytes, 14);
        //后段
        checksum = ByteUtil.sum(bytes, 6, length);
        bytes[length + 6] = checksum;
        bytes[length + 7] = (byte) tail;
        return bytes;
    }

    private void dataBuffer(byte[] bs, int position) {
        for (RunaFrameSequence.DataUnit dataUnit : dataField) {
            System.arraycopy(dataUnit.getData(), 0, bs, position, dataUnit.length());
            position += dataUnit.length();
        }
    }

    /**
     * 琅卡博测试
     *
     * @param args
     */
    public static void main(String[] args) {
        String area = "63116359";
//        String meterSer = "000000" + "11259284";
//        String meterSer = "0000" + "11259284";
//        String meterSer="00000000"+"1234567811259284";
//        String meterSer="1234567811259284";
        String meterSer="11259284";
        byte[] bytes1 = ByteUtil.hexStringToByte(meterSer);
        byte[] data = ByteUtil.merge(bytes1, RunaFrameSequence.fnToBin(30));

        int dus = 0;
//        for (RunaFrameSequence.DataUnit dataUnit : dataField) {
//            dus += dataUnit.length();
//        }
        dus += data.length;
        int length = 1 + 5 + 2 + dus; //C + A + afn + seq + data unit
//        int L = (length) | 2; //1111 1111 1111 1110B
        int L = (length); //1111 1111 1111 1110B
        byte[] bytes = new byte[length + 8];
        //前段
        bytes[0] = (byte) 0x68;
        bytes[1] = (byte) L;
        bytes[2] = (byte) (L >> 8);
        bytes[3] = (byte) L;
        bytes[4] = (byte) (L >> 8);
        bytes[5] = (byte) 0x68;
//        bytes[6] = new RunaFrameSequence.Control(0, 1, 0, 0, AppFunCode.prmFunCode.PRM1_RequestDataOne).getC();
        bytes[6] = 0x41;
        //中段
        System.arraycopy(new RunaFrameSequence.Area(area).getA(), 0, bytes, 7, 5);
        bytes[12] = (byte) AppFunCode.rnicAFN.RequestDataOne.getCode();
        bytes[13] = new RunaFrameSequence.Seq(0, 1, 1, 1, 0).getSeq();
//        dataBuffer(bytes, 14);


//        System.arraycopy(data, 0, bytes, 14, 4 + (data==null||data.length==0 ? 0 : data.length));
        System.arraycopy(data, 0, bytes, 14, data.length);
//        14 += 4 + (data==null||data.length==0 ? 0 : data.length);
        //后段
        bytes[length + 6] = ByteUtil.sum(bytes, 6, length);
        bytes[length + 7] = (byte) 0x16;
        System.out.println(ByteUtil.byteToHexString(bytes));
    }

}
